import { View, Text, Button, Input, Slider, Audio } from '@tarojs/components'
import { useState, useEffect, useRef } from 'react'
import Taro from '@tarojs/taro'
import './index.less'

export default function TTSComponent({ visible, onClose }) {
  // 状态管理
  const [isConnected, setIsConnected] = useState(false)
  const [isConnecting, setIsConnecting] = useState(false)
  const [isSynthesizing, setIsSynthesizing] = useState(false)
  const [text, setText] = useState('你好，这是一个语音合成测试。')
  const [logs, setLogs] = useState([])
  const [errorMessage, setErrorMessage] = useState('')
  const [audioUrl, setAudioUrl] = useState('')
  const [isPlaying, setIsPlaying] = useState(false)

  // TTS参数配置
  const [ttsParams, setTtsParams] = useState({
    voice: 'zhitian_emo', // 默认音色
    pitch: 0,             // 音调 (-500 到 500)
    speed: 0,             // 语速 (-500 到 500)
    volume: 50            // 音量 (0 到 100)
  })

  // 音色选项
  const voiceOptions = [
    { value: 'zhitian_emo', label: '知甜（情感）' },
    { value: 'zhimiao_emo', label: '知妙（情感）' },
    { value: 'zhixiaoxia', label: '知夏' },
    { value: 'zhiyan', label: '知燕' },
    { value: 'zhishuo', label: '知硕' },
    { value: 'zhixiaobai', label: '知小白' },
    { value: 'zhiqi', label: '知琪' },
    { value: 'zhiyuan', label: '知媛' }
  ]

  // WebSocket引用
  const wsRef = useRef(null)
  const audioChunksRef = useRef([])

  // WebSocket服务器配置
  const WS_URL = 'wss://www.yzyt.xyz/ws/tts'

  // 添加日志
  const addLog = (message) => {
    const timestamp = new Date().toLocaleTimeString()
    setLogs(prev => [{ time: timestamp, message }, ...prev.slice(0, 19)]) // 保留最新20条
  }

  // 显示错误
  const showError = (message) => {
    setErrorMessage(message)
    setTimeout(() => setErrorMessage(''), 5000)
  }

  // 连接WebSocket
  const connectToServer = () => {
    if (wsRef.current && wsRef.current.readyState !== WebSocket.CLOSED) {
      addLog('连接已存在')
      return
    }

    setIsConnecting(true)
    addLog('正在连接到WebSocket服务器...')

    wsRef.current = new WebSocket(WS_URL)

    wsRef.current.onopen = () => {
      setIsConnected(true)
      setIsConnecting(false)
      addLog('已成功连接到服务器')
      setErrorMessage('')
    }

    wsRef.current.onmessage = (event) => {
      if (event.data instanceof Blob) {
        // 接收音频数据
        audioChunksRef.current.push(event.data)
        addLog(`接收音频数据块，大小: ${event.data.size} bytes`)
      } else {
        try {
          const message = JSON.parse(event.data)
          addLog(`收到消息: ${event.data}`)

          if (message.type === 'synthesis_complete') {
            handleSynthesisComplete()
          } else if (message.type === 'error') {
            showError(message.message || '合成过程中发生错误')
            setIsSynthesizing(false)
          }
        } catch (e) {
          addLog(`收到无法解析的消息: ${event.data}`)
        }
      }
    }

    wsRef.current.onerror = (error) => {
      showError('WebSocket连接错误')
      addLog('连接错误')
      setIsConnecting(false)
    }

    wsRef.current.onclose = (event) => {
      if (event.code === 1000) {
        addLog('连接已正常关闭')
      } else {
        addLog(`连接已关闭，代码: ${event.code}`)
      }

      setIsConnected(false)
      setIsConnecting(false)
      setIsSynthesizing(false)
    }
  }

  // 断开连接
  const disconnectFromServer = () => {
    if (wsRef.current) {
      wsRef.current.close(1000, '用户主动断开')
      addLog('正在断开连接...')
    }
  }

  // 开始语音合成
  const startSynthesis = () => {
    if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
      showError('请先连接到服务器')
      return
    }

    if (!text.trim()) {
      showError('请输入要合成的文本')
      return
    }

    setIsSynthesizing(true)
    audioChunksRef.current = []
    setAudioUrl('')
    addLog('开始语音合成...')

    // 发送合成请求
    const request = {
      text: text.trim(),
      voice: ttsParams.voice,
      pitch: ttsParams.pitch,
      speed: ttsParams.speed,
      volume: ttsParams.volume
    }

    wsRef.current.send(JSON.stringify(request))
    addLog(`发送合成请求: ${JSON.stringify(request)}`)
  }

  // 处理合成完成
  const handleSynthesisComplete = () => {
    setIsSynthesizing(false)
    addLog('语音合成完成')

    if (audioChunksRef.current.length > 0) {
      // 合并音频数据
      const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/wav' })
      const url = URL.createObjectURL(audioBlob)
      setAudioUrl(url)
      addLog(`音频文件已生成，大小: ${audioBlob.size} bytes`)
    } else {
      addLog('未接收到音频数据')
    }
  }

  // 参数更新处理
  const updateParam = (key, value) => {
    setTtsParams(prev => ({ ...prev, [key]: value }))
  }

  // 清除日志
  const clearLogs = () => {
    setLogs([])
    addLog('日志已清除')
  }

  // 播放音频
  const playAudio = () => {
    if (audioUrl) {
      setIsPlaying(true)
      addLog('开始播放音频')
    }
  }

  // 音频播放结束
  const onAudioEnded = () => {
    setIsPlaying(false)
    addLog('音频播放结束')
  }

  // 组件卸载时清理资源
  useEffect(() => {
    return () => {
      if (wsRef.current) {
        wsRef.current.close()
      }
      if (audioUrl) {
        URL.revokeObjectURL(audioUrl)
      }
    }
  }, [])

  // 获取连接状态类名
  const getConnectionStatusClass = () => {
    if (isConnected) return 'status-connected'
    if (isConnecting) return 'status-connecting'
    return 'status-disconnected'
  }

  if (!visible) return null

  return (
    <View className='tts-container'>
      <View className='tts-header'>
        <Text className='tts-title'>阿里云TTS WebSocket测试工具</Text>
        <Button className='close-btn' onClick={onClose}>×</Button>
      </View>

      {errorMessage && (
        <View className='error-panel'>
          <Text>{errorMessage}</Text>
        </View>
      )}

      <View className='connection-panel'>
        <View className='panel-header'>
          <Text className='panel-title'>连接控制</Text>
          <View className={`connection-status ${getConnectionStatusClass()}`}>
            <View className='status-dot'></View>
            <Text className='status-text'>
              {isConnected ? '已连接' : isConnecting ? '连接中...' : '未连接'}
            </Text>
          </View>
        </View>
        
        <View className='button-group'>
          <Button 
            className={`btn btn-primary ${isConnected ? 'btn-disabled' : ''}`}
            disabled={isConnected || isConnecting}
            onClick={connectToServer}
          >
            连接
          </Button>
          <Button 
            className={`btn btn-danger ${!isConnected ? 'btn-disabled' : ''}`}
            disabled={!isConnected}
            onClick={disconnectFromServer}
          >
            断开
          </Button>
        </View>
      </View>

      <View className='text-panel'>
        <Text className='panel-title'>文本输入</Text>
        <View className='text-input-container'>
          <Input
            className='text-input'
            type='text'
            placeholder='请输入要合成的文本...'
            value={text}
            onInput={(e) => setText(e.detail.value)}
            maxlength={500}
          />
          <View className='text-counter'>
            <Text>{text.length}/500</Text>
          </View>
        </View>
        <Button 
          className={`btn btn-primary btn-synthesis ${!isConnected || isSynthesizing ? 'btn-disabled' : ''}`}
          disabled={!isConnected || isSynthesizing}
          onClick={startSynthesis}
        >
          {isSynthesizing ? '合成中...' : '开始合成'}
        </Button>
      </View>

      <View className='params-panel'>
        <Text className='panel-title'>参数设置</Text>
        
        <View className='param-group'>
          <Text className='param-label'>音色选择</Text>
          <View className='voice-selector'>
            {voiceOptions.map(option => (
              <Button
                key={option.value}
                className={`voice-btn ${ttsParams.voice === option.value ? 'voice-btn-active' : ''}`}
                onClick={() => updateParam('voice', option.value)}
              >
                {option.label}
              </Button>
            ))}
          </View>
        </View>

        <View className='param-group'>
          <Text className='param-label'>音调: {ttsParams.pitch}</Text>
          <Slider
            className='param-slider'
            min={-500}
            max={500}
            value={ttsParams.pitch}
            step={10}
            onChange={(e) => updateParam('pitch', e.detail.value)}
          />
        </View>

        <View className='param-group'>
          <Text className='param-label'>语速: {ttsParams.speed}</Text>
          <Slider
            className='param-slider'
            min={-500}
            max={500}
            value={ttsParams.speed}
            step={10}
            onChange={(e) => updateParam('speed', e.detail.value)}
          />
        </View>

        <View className='param-group'>
          <Text className='param-label'>音量: {ttsParams.volume}</Text>
          <Slider
            className='param-slider'
            min={0}
            max={100}
            value={ttsParams.volume}
            step={1}
            onChange={(e) => updateParam('volume', e.detail.value)}
          />
        </View>
      </View>

      <View className='audio-panel'>
        <Text className='panel-title'>音频播放器</Text>
        {audioUrl ? (
          <View className='audio-container'>
            <Audio
              className='audio-player'
              src={audioUrl}
              controls
              onPlay={() => setIsPlaying(true)}
              onPause={() => setIsPlaying(false)}
              onEnded={onAudioEnded}
            />
            <View className='audio-info'>
              <Text>音频已生成，可以播放</Text>
            </View>
          </View>
        ) : (
          <View className='audio-placeholder'>
            <Text>暂无音频文件</Text>
          </View>
        )}
      </View>

      <View className='logs-panel'>
        <View className='logs-header'>
          <Text className='panel-title'>事件日志</Text>
          <Button className='btn btn-small' onClick={clearLogs}>清除日志</Button>
        </View>
        <View className='logs-content'>
          {logs.map((log, index) => (
            <View key={index} className='log-entry'>
              <Text className='log-time'>[{log.time}]</Text>
              <Text className='log-message'>{log.message}</Text>
            </View>
          ))}
        </View>
      </View>
    </View>
  )
}